package com.base.cn.platform.os.controller.user.user;

import com.base.cn.platform.os.common.constants.CacheConstants;
import com.base.cn.platform.os.common.controller.BaseController;
import com.base.cn.platform.os.common.j2cache.CustomCacheChannel;
import com.base.cn.platform.os.common.j2cache.J2CacheRegion;
import com.base.cn.platform.os.common.md5.MD5;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.rsa.WebRsaUtils;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.Security.PurseSecurityUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.common.utils.user.UserExpandFrom;
import com.base.cn.platform.os.entity.manage.subject.SysSubject;
import com.base.cn.platform.os.entity.user.user.CusUser;
import com.base.cn.platform.os.entity.user.user.UserCondition;
import com.base.cn.platform.os.service.manage.order.goods.OrderService;
import com.base.cn.platform.os.service.manage.subject.SysSubjectBiz;
import com.base.cn.platform.os.service.user.user.CusUserBiz;
import com.base.cn.platform.os.service.user.user.UserLoginBiz;
import com.base.cn.platform.os.service.user.user.ValidateUser;
import com.github.pagehelper.PageInfo;
import com.google.gson.reflect.TypeToken;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 学员接口
 *
 * @author ll
 * @create 2018-04-10-13:36
 */
@RestController
@RequestMapping("/manage/user")
public class CusUserController extends BaseController {
    @Autowired
    private CusUserBiz cusUserBiz;
    @Autowired
    private ValidateUser validateUser;
    @Autowired
    private SysSubjectBiz sysSubjectBiz;
    @Autowired
    private OrderService orderService;
    @Autowired
    private UserLoginBiz userLoginBiz;
    @Autowired
    private CustomCacheChannel customCacheChannel;


    /**
     * 分页搜索学员用户列表
     * @param currentPage 分页
     * @param user 用户条件
     * @return
     */
    @RequestMapping("/queryUserListPage")
    public PageInfo<CusUser> queryUserListPage(@RequestBody UserCondition user,
                                               @RequestParam(value = "currentPage",defaultValue = "1",required = false) int currentPage,
                                               @RequestParam(value = "subjectData",defaultValue = "false",required = false) boolean subjectData,
                                               @RequestParam(value = "userAddresses",defaultValue = "false",required = false) boolean userAddresses,
                                               @RequestParam(value = "expRule",defaultValue = "false",required = false) boolean expRule,
                                               @RequestParam(value = "gradeConfig",defaultValue = "false",required = false)  boolean gradeConfig,
                                               @RequestParam(value = "integral",defaultValue = "false",required = false)  boolean integral,
                                               @RequestParam(value = "userMember",defaultValue = "false",required = false)  boolean userMember,
                                               @RequestParam(value = "expAccount",defaultValue = "false",required = false)  boolean expAccount){
        Pagination page = new Pagination();
        page.setCurrentPage(currentPage);
        user.setOrderBy(1);
        return cusUserBiz.queryUserListPage(page,user,subjectData,userAddresses,expRule,gradeConfig,integral,userMember,expAccount);
    }


    /**
     * 分页搜索学员用户列表
     * @param user 用户条件
     * @param currentPage 分页
     * @param pageSize 查询数量
     * @return
     */
    @RequestMapping("/findUserListPage")
    public PageInfo<CusUser> findUserListPage(@RequestBody UserCondition user,
                                               @RequestParam("currentPage") int currentPage,
                                               @RequestParam("pageSize") int pageSize){
        Pagination page = new Pagination();
        page.setCurrentPage(currentPage);
        page.setPageSize(pageSize);
//        user.setOrderBy(1);
        return cusUserBiz.queryUserListPage(page,user);
    }

    /**
     * 多条件查询学员用户数据列表
     * @param containColumns 查询条件
     * @param subjectData 是否设置专业
     * @param userAddresses 是否设置收货地址
     * @param expRule 是否设置经验规则
     * @param gradeConfig 是否设置经验
     * @param integral 是否设置积分
     * @param userMember 是否设置会员数据
     * @param expAccount 是否设置账户数据
     * @return List<CusUser>
     */
    @RequestMapping("/queryUserList")
    public List<CusUser> queryUserList(@RequestBody UserCondition containColumns,
                                       @RequestParam(value = "subjectData",defaultValue = "false",required = false) boolean subjectData,
                                       @RequestParam(value = "userAddresses",defaultValue = "false",required = false) boolean userAddresses,
                                       @RequestParam(value = "expRule",defaultValue = "false",required = false) boolean expRule,
                                       @RequestParam(value = "gradeConfig",defaultValue = "false",required = false)  boolean gradeConfig,
                                       @RequestParam(value = "integral",defaultValue = "false",required = false)  boolean integral,
                                       @RequestParam(value = "userMember",defaultValue = "false",required = false)  boolean userMember,
                                       @RequestParam(value = "expAccount",defaultValue = "false",required = false)  boolean expAccount){
        return cusUserBiz.queryUserList(containColumns,null,null,subjectData,userAddresses,expRule,gradeConfig,integral,userMember,expAccount);
    }

    /**
     * 根据手机搜索用户
     * @param mobile
     * @return
     */
    @RequestMapping("/queryUserMobile")
    public CusUser queryUserMobile(@RequestParam("mobile")String mobile){
        return cusUserBiz.queryUserByMobile(mobile);
    }


    /**
     * 根据邮箱搜索用户
     * @param email
     * @return
     */
    @RequestMapping("/queryUserEmail")
    public CusUser queryUserEmail(@RequestParam("email")String email){
        return cusUserBiz.queryUserByEmail(email);
    }

    /**
     * 根据登录账号搜索用户
     * @param loginAccount
     * @return
     */
    @RequestMapping("/queryUserLoginAccount")
    public CusUser queryUserLoginAccount(@RequestParam("loginAccount")String loginAccount){
        return cusUserBiz.queryUserByLoginAccount(loginAccount);
    }

    /**
     * 通过UUID获取用户对象
     * @param uuid IOS的手机串号
     * @return 用户对象
     */
    @RequestMapping("/queryUserByUUID")
    public Map<String, Object> queryUserByUUID(@RequestParam("uuid") String uuid){
        CusUser cusUser = cusUserBiz.queryUserByLoginAccount(uuid);
        if(ObjectUtils.isEmpty(cusUser)){
            cusUser = new CusUser();
            cusUser.setLoginAccount(uuid);
            cusUser.setNickname("IOS用户"+StringUtils.getRandomString(6));
            cusUser.setUserType(1);
            cusUser.setPassword(uuid);
            cusUser.setRegisterFrom(UserExpandFrom.ios.getKey());
            cusUserBiz.createUser(cusUser);
          /*  //创建学习记录表
            userLoginBiz.createUserShardingTable(cusUser.getId());*/
        }
        userLoginBiz.setUserLoginInfo(cusUser,false,null);
        cusUser.setPassword(null);
        cusUser.setCustomerkey(null);
        String sessionId = MD5.getMD5(StringUtils.getRandomString(32)+System.currentTimeMillis()+cusUser.getId());
        String s = gson.toJson(cusUser);
        customCacheChannel.set(J2CacheRegion.THIRTY_DAY_REGION.getKey(),sessionId,s);
        customCacheChannel.set(J2CacheRegion.THIRTY_DAY_REGION.getKey(),sessionId+ CacheConstants.SHARE_KEY_SUFFIX,MD5.getMD5(cusUser.getId().toString())+"_"+cusUser.getId());
        userLoginBiz.setUserToken(cusUser.getId(),sessionId);
        Map<String, Object> map = gson.fromJson(s, new TypeToken<Map<String, Object>>(){}.getType());
        map.put("sessionId",sessionId);
        return map;
    }


    /**
     * 添加用户
     * @param user
     * @param isAdminCreate 是不是后台创建（不包括批量导入）
     * @return
     */
    @RequestMapping("/saveUser")
    public Map<String,Object> saveUser(@RequestBody CusUser user,
                                       @RequestParam(value = "isAdminCreate",required = false,defaultValue = "false") boolean isAdminCreate,
                                       @RequestParam(value = "courseIds",required = false) String courseIds) throws Exception{
        //根据课程IDS  搜索专业和 科目   Id  and Ids  添加到User 中
        if(isAdminCreate){
            if(!ObjectUtils.isNotEmpty(user)){
                return ResultUtil.ERROR("请输入提交数据！");
            }
            if(StringUtils.isEmpty(user.getMobile())){
                return ResultUtil.ERROR("请输入添加手机号！");
            }
            String message = StringUtils.checkSubjectCondition(user.getSubjectIds());
            if(message !=null){
                return ResultUtil.ERROR(message);
            }
            if(StringUtils.isEmpty(user.getPassword())){
                return ResultUtil.ERROR("请输入添加密码！");
            }
        }
        Map<String,Object> _map = validateUser.vUserData(user);
        if (ObjectUtils.isEmpty(_map)){
            user =cusUserBiz.createUser(user);
            if(StringUtils.isNotEmpty(courseIds)){//免费赠送课程
                courseIds = StringUtils.subHeadTailString(courseIds,",");
                String[] arr = courseIds.split(",");
                String shopData = Arrays.stream(arr).collect(Collectors.joining("-COURSE-1,","","-COURSE-1"));
                orderService.createFreeOrder(user.getId(),shopData);
            }
            return ResultUtil.SUCCESS("添加成功",user);
        }
        return _map;
    }


    /**
     * 修改账户状态
     * @param userIds
     * @return
     */
    @RequestMapping("/updateCusUserStatus")
    public Map<String,Object> updateCusUserStatus(@RequestParam("userIds")String userIds,
                                                  @RequestParam("status")Integer status){
        String  message="系统繁忙,请稍候再试";
        if (StringUtils.isEmpty(userIds)){
            return ResultUtil.ERROR(message);
        }

        if(status==1){ message="恢复成功";
        }else if(status==2){ message="封禁成功"; }
        cusUserBiz.updateUserStatusByUserIds(userIds,status);
        return ResultUtil.SUCCESS(message);
    }

    /**
     * 获取用户的学业信息
     * @param userId 用户ID
     * @return 专业Map，key=subjectList基础专业，kye=attachSubjectList附加专业
     */
    @RequestMapping("/findUserAcademic")
    public Map<String,List<SysSubject>> findUserAcademic(@RequestParam("userId") BigDecimal userId){
        Map<String,List<SysSubject>> stringListMap = new HashMap<>();
        //基础专业
        List<SysSubject> sysSubjectList = cusUserBiz.getUserNaturalSubject(userId);
        stringListMap.put("subjectList",sysSubjectList);
        //附加专业
        List<SysSubject> attachSubjectList = cusUserBiz.findUserSubjectData(userId);
        //过滤附加专业中重复的基础专业
        if(ObjectUtils.isNotEmpty(sysSubjectList) && ObjectUtils.isNotEmpty(attachSubjectList)){
            sysSubjectList.forEach(e->{
                List<SysSubject> childSubjectList = e.getChildSubjectList();
                if(ObjectUtils.isNotEmpty(childSubjectList)){
                    attachSubjectList.forEach(_e->{
                        List<SysSubject> _childSubjectList = _e.getChildSubjectList();
                        if (ObjectUtils.isNotEmpty(_childSubjectList)){
                            _childSubjectList.removeAll(childSubjectList);
                        }
                    });
                }
            });
        }
        stringListMap.put("attachSubjectList",attachSubjectList);
        return stringListMap;
    }

    /**
     * 获取用户的学业数据
     * @param userId 用户ID
     * @return 学业信息
     */
    @RequestMapping("/getUserNaturalSubject")
    public List<SysSubject> getUserNaturalSubject(@RequestParam("userId") BigDecimal userId){
        return cusUserBiz.getUserNaturalSubject(userId);
    }

    /**
     * 获取学员可以选择父级专业列表
     * @param userId 用户ID
     * @return List<Map<String,Object>>
     */
    @RequestMapping("/findUserSureSelectParentList")
    public Map<String,Object> findUserSureSelectParentList(@RequestParam("userId") BigDecimal userId){
        List<SysSubject> list = cusUserBiz.getUserNaturalSubject(userId);
        String parentIds = null;
        if(ObjectUtils.isNotEmpty(list)){
            parentIds =list.stream().map(e->e.getId().toString()).collect(Collectors.joining(","));
        }
        SysSubject sysSubject = new SysSubject();
        sysSubject.setParentId(BigDecimal.ZERO);
        sysSubject.setNotIds(parentIds);
        sysSubject.setStatus(1);
        List<SysSubject> parentSubjectList = sysSubjectBiz.findSubjectList(sysSubject);
        if(ObjectUtils.isNotEmpty(parentSubjectList)){
            return ResultUtil.SUCCESS(parentSubjectList);
        }else{
            return ResultUtil.ERROR("没有可添加的专业");
        }
    }

    /**
     * 查询用户可以选择的学业子级专业
     * @param userId 用户ID
     * @param parentIds 父级ID串，多个以“,”隔开
     * @return Map<String,Object>
     */
    @RequestMapping("/findUserSureSelectChildList")
    public Map<String,Object> findUserSureSelectChildList(@RequestParam("userId") BigDecimal userId,
                                                          @RequestParam("parentIds") String parentIds){

        if(StringUtils.isEmpty(parentIds)){
            return ResultUtil.ERROR("请设置父级专业");
        }
        List<SysSubject> list = cusUserBiz.getUserNaturalSubject(userId);
        String childIds = null;
        if(ObjectUtils.isNotEmpty(list)){
            StringBuffer stringBuffer = new StringBuffer();
            list.forEach(e->{
                if((","+parentIds+",").contains(String.valueOf(e.getId()))){
                    List<SysSubject> childList = e.getChildSubjectList();
                    if(ObjectUtils.isNotEmpty(childList)){
                        String _childIds = childList.stream().map(em->em.getId().toString()).collect(Collectors.joining(","));
                        stringBuffer.append(_childIds).append(",");
                    }
                }
            });
            childIds = stringBuffer.toString();
            if(StringUtils.isNotEmpty(childIds)){
                childIds = StringUtils.subHeadTailString(childIds,",");
            }
        }
        SysSubject sysSubject = new SysSubject();
        sysSubject.setParentIds(parentIds);
        sysSubject.setNotIds(childIds);
        sysSubject.setStatus(1);
        List<SysSubject> childSubjectList = sysSubjectBiz.findSubjectList(sysSubject);
        if(ObjectUtils.isNotEmpty(childSubjectList)){
            return ResultUtil.SUCCESS(childSubjectList);
        }else{
            return ResultUtil.ERROR("没有可添加的科目");
        }
    }

    /**
     * 用户详情
     * @param userId
     * @return
     */
    @RequestMapping("/userInfo")
    public CusUser  userInfo(@RequestParam("userId")BigDecimal userId,
                             @RequestParam("subjectData")boolean subjectData,
                             @RequestParam("userAddresses")boolean userAddresses,
                             @RequestParam("expRule")boolean expRule,
                             @RequestParam("gradeConfig")boolean gradeConfig,
                             @RequestParam("integral")boolean integral,
                             @RequestParam("userMember")boolean userMember,
                             @RequestParam("expAccount")boolean expAccount
    ){
        return cusUserBiz.queryUserById(userId,subjectData,userAddresses,expRule,gradeConfig,integral,userMember,expAccount);
    }

    /**
     * 用户学习中心详情
     * @param condition
     * @return
     */
    @RequestMapping("/userStudyInfo")
    public CusUser  userStudyInfo(@RequestBody UserCondition condition){
        return cusUserBiz.userStudyInfo(condition);
    }

    /**
     * 保存用户头像
     * @param userId 用户ID
     * @param avatar 用户新头像
     * @return Map<String,Object>
     */
    @RequestMapping("/saveUserAvatar")
    public Map<String,Object> saveUserAvatar(@RequestParam("userId") BigDecimal userId,
                                             @RequestParam("avatar") String avatar){
        if(StringUtils.isEmpty(avatar)){
            return ResultUtil.ERROR("请上传头像");
        }
        CusUser user = new CusUser();
        user.setAvatar(avatar);
        cusUserBiz.updateByWhereSql(user,"id="+userId);
        return ResultUtil.SUCCESS("头像保存成功",user);
    }


    /**
     * 修改账户状态
     * @param userIds
     * @return
     */
    @RequestMapping("/queryCusUserMapByUserIds")
    public Map<BigDecimal,CusUser> queryCusUserMapByUserIds(@RequestParam("userIds")String userIds,
                                                            @RequestParam("subjectData")boolean subjectData,
                                                            @RequestParam("userAddresses")boolean userAddresses,
                                                            @RequestParam("expRule")boolean expRule,
                                                            @RequestParam("gradeConfig")boolean gradeConfig,
                                                            @RequestParam("integral")boolean integral,
                                                            @RequestParam("userMember")boolean userMember,
                                                            @RequestParam("expAccount")boolean expAccount){
        List<CusUser> cusUsers = cusUserBiz.queryUserByIds(userIds,subjectData,userAddresses,expRule,gradeConfig,integral,userMember,expAccount);
        if(ObjectUtils.isNotEmpty(cusUsers)){
            Map<BigDecimal,CusUser> cusUserMap =cusUsers.stream().collect(Collectors.toMap(CusUser::getId,e->e));
            return cusUserMap;
        }
        return null;
    }


    /**
     * 创建用户数据
     * @param user
     * @return CusUser
     */
    @RequestMapping("/createUser")
    public CusUser createUser(@RequestBody CusUser user){
        return cusUserBiz.createUser(user);
    }

    /**
     * 通过手机号码去查询用户，如果没有的话，创建用户  (仅供分销系统使用)
     * @param mobile
     * @return
     */
    @RequestMapping("/queryUserOrSaveUserByMobile")
    public CusUser queryUserOrSaveUserByMobile(@RequestParam("mobile") String mobile) throws Exception{
        CusUser cusUser = cusUserBiz.queryUserByMobile(mobile);
        if(ObjectUtils.isEmpty(cusUser)){
            CusUser _cusUser = new CusUser();
            _cusUser.setRegisterFrom(UserExpandFrom.adminFrom.getKey());
            _cusUser.setMobile(mobile);
            _cusUser.setPassword("000000");
            Map<String, Object> result = this.saveUser(_cusUser,false,null);
            if(ObjectUtils.isNotEmpty(result) && (Boolean) result.get("success")){
                return (CusUser)result.get("entity");
            }
        }
        return cusUser;
    }

    /**
     * 重置密码
     *
     * @param userId
     * @return
     */
    @RequestMapping("/resetPassword")
    public Map<String, Object> resetPassword(@RequestParam("userId") BigDecimal userId,
                                             @RequestParam("rPassword") String rPassword) {
        Map<String,Object> result = validateUser.validatePwd(rPassword);
        if(result!=null){
            return  result;
        }
        cusUserBiz.resetPassword(userId,rPassword);
        return ResultUtil.SUCCESS("重置成功", null);
    }

    /**
     * 用户修改密码
     * @param userId     用户ID
     * @param nowPwd     用户原密码
     * @param newPwd     新密码
     * @param confirmPwd 确认密码
     */
    @RequestMapping("/updateUserPwd")
    public Map<String,Object> updateUserPwd(@RequestParam("userId") BigDecimal userId,
                                            @RequestParam("nowPwd") String nowPwd,
                                            @RequestParam("newPwd") String newPwd,
                                            @RequestParam("confirmPwd") String confirmPwd,
                                            @RequestParam("sign") String sign) throws Exception{
        if(StringUtils.isEmpty(nowPwd)){
            return ResultUtil.ERROR("请输入原密码");
        }
        if(StringUtils.isEmpty(newPwd)){
            return ResultUtil.ERROR("请输入新密码");
        }
        //解密密码
        nowPwd = WebRsaUtils.decrypt(customCacheChannel,sign,nowPwd,false);
        confirmPwd = WebRsaUtils.decrypt(customCacheChannel,sign,confirmPwd,false);
        newPwd = WebRsaUtils.decrypt(customCacheChannel,sign,newPwd,true);
        Map<String,Object> result = validateUser.validatePwd(newPwd);
        if(result !=null){
            return result;
        }
        if(!newPwd.equals(confirmPwd)){
            return ResultUtil.ERROR("两次密码不一致");
        }
        CusUser user = cusUserBiz.findById(userId);
        if(!PurseSecurityUtils.secrect(nowPwd, user.getCustomerkey()).equals(user.getPassword())){
            return ResultUtil.ERROR("原密码错误");
        }
        cusUserBiz.resetPassword(userId,newPwd);
        return ResultUtil.SUCCESS("密码修改成功");
    }

    /**
     * 修改用户选择的专业
     * @param userId 用户ID
     * @param naturalSubjectIds 用户选择专业ID
     * @return CusUser
     */
    @RequestMapping("/updateUserNaturalSubjectIds")
    public Map<String,Object> updateUserNaturalSubjectIds(@RequestParam("userId")BigDecimal userId,
                                                          @RequestParam("naturalSubjectIds")String naturalSubjectIds){
        CusUser cusUser = cusUserBiz.findById(userId);
        if(ObjectUtils.isEmpty(cusUser)){
            return ResultUtil.ERROR("用户不存在");
        }
        if(StringUtils.isEmpty(naturalSubjectIds)){
            return ResultUtil.ERROR("请选择专业/科目");
        }
        this.dealWithDeleteUserNatyralSubjectIds(cusUser);//处理用户选择专业id串中已删除专业
        Map<String,Object> resultMap = vUserNaturalSubjectIds(cusUser.getNaturalSubjectIds(),naturalSubjectIds);
        if(ObjectUtils.isNotEmpty(resultMap)){
            return resultMap;
        }
        cusUserBiz.updateUserNaturalSubjectIds(cusUser,naturalSubjectIds);
        return ResultUtil.SUCCESS();
    }

    /**
     * 修改用户附加专业
     * @param userId 用户Id
     * @param subjectIds 专业Ids
     */
    @RequestMapping("/updateUserAttachSubjectIds")
    public void updateUserAttachSubjectIds(@RequestParam("userId")BigDecimal userId,
                                           @RequestParam("subjectIds")String subjectIds){
        cusUserBiz.updateUserAttachSubjectIds(userId,subjectIds);
    }


    /**
     * 修改用户基本信息 API
     *
     * @param user 用户属性对象
     */
    @RequestMapping("/updateUser")
    public Map<String, Object> updateUser(@RequestBody CusUser user) {
        if (!ObjectUtils.isNotEmpty(user)) {
            return ResultUtil.ERROR("系统繁忙，请稍后再试");
        }
        CusUser _user = cusUserBiz.findById(user.getId());
        if (!ObjectUtils.isNotEmpty(_user)) {
            return ResultUtil.ERROR("用户不存在");
        }
        if(StringUtils.isNotEmpty(user.getNickname())){
            try {
                _user.setNickname(replaceUnsupportedCharSequence(URLDecoder.decode(user.getNickname().trim(), "utf-8")));
            } catch (UnsupportedEncodingException e) {
                return  ResultUtil.ERROR("用户昵称填写异常");
            }
            _user.setNickname(replaceUnsupportedCharSequence(_user.getNickname()));
            if (_user.getNickname().length() > 12) {
                return ResultUtil.ERROR("用户昵称不能超过12个字");
            }
        }
        if (ObjectUtils.isNotEmpty(user.getBirthday())) {
            _user.setBirthday(user.getBirthday());
            if (!ObjectUtils.isNotEmpty(_user.getBirthday())) {
                return ResultUtil.ERROR("请填写用户生日");
            }
        }
        if (user.getGender() != null && user.getGender() >= 0) {
            _user.setGender(user.getGender());
            if (_user.getGender() == null || _user.getGender() < 0) {
                return ResultUtil.ERROR("请选择用户性别");
            }
        }
        if (StringUtils.isNotEmpty(user.getRealName())) {
            try {
                _user.setRealName(URLDecoder.decode(user.getRealName(), "utf-8"));
            } catch (UnsupportedEncodingException e) {
                return  ResultUtil.ERROR("用户真实姓名填写异常");
            }
            if (StringUtils.isEmpty(_user.getRealName())) {
                return ResultUtil.ERROR("请填写用户真实姓名");
            }
            _user.setNickname(replaceUnsupportedCharSequence(_user.getNickname()));
        }
        if (StringUtils.isNotEmpty(user.getUserInfo())) {
            _user.setUserInfo(replaceUnsupportedCharSequence(user.getUserInfo()));
            if (StringUtils.isEmpty(_user.getUserInfo())) {
                return ResultUtil.ERROR("请填写用户签名");
            }
            _user.setRealName(replaceUnsupportedCharSequence(_user.getRealName()));
        }
        if (ObjectUtils.isNotEmpty(user.getLastSystemTime())) {
            _user.setLastSystemTime(user.getLastSystemTime());
        }
        cusUserBiz.updateById(_user,null);
        return ResultUtil.SUCCESS("用户基本信息修改成功", gson.toJson(_user));
    }

    /**
     * 更新学员用户信息
     *
     * @param userId 学员id
     * @param property 要修改的属性
     * @param increase
     */
    @RequestMapping("/updateUserNumberOfStatistics")
    public void updateUserNumberOfStatistics(@RequestParam("userId") BigDecimal userId,
                                             @RequestParam("property") String property,
                                             @RequestParam("increase") Integer increase){
        cusUserBiz.updateUserNumberOfStatistics(userId, property, increase);
    }

    /**
     * 获取用户的附加专业数据
     * @param userId 用户ID
     * @return List<Map<String,Object>>
     */
    @RequestMapping("/findUserSubjectData")
    public List<SysSubject> findUserSubjectData(@RequestParam("userId") BigDecimal userId){
        return cusUserBiz.findUserSubjectData(userId);
    }


    /**
     * 修改最后获取作业的时间
     * @param userId
     * @param lastWorkTime
     * @return
     */
    @RequestMapping("/updateUserLastWorkTime")
    public Map<String,Object> updateUserLastWorkTime(@RequestParam("userId") BigDecimal userId,
                                                     @RequestParam("lastWorkTime") String lastWorkTime){
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(lastWorkTime, pos);
        cusUserBiz.updateUserLastWorkTime(userId,strtodate);
        return ResultUtil.SUCCESS();
    }

    /**
     * 检验手机号是否已存在于用户中
     * @param mobileList 手机列表
     * @return
     */
    @RequestMapping("/validateUserMobile")
    public Map<String, Object> validateUserMobile(@RequestParam("mobileList") List<String> mobileList){
        List<CusUser> cusUsers = cusUserBiz.queryUserByMobileList(mobileList);
        if(ObjectUtils.isNotEmpty(cusUsers)){
            return ResultUtil.ERROR("", cusUsers);
        }else {
            return ResultUtil.SUCCESS();
        }
    }

    /**
     * 根据手机号批量创建用户
     * @param mobileList 手机号
     * @return Map<String, Object>
     */
    @RequestMapping("/createUserByMobileList")
    public Map<String, Object> createUserByMobileList(@RequestParam("mobileList") List<String> mobileList){
        try{
            if (ObjectUtils.isNotEmpty(mobileList)) {
                List<CusUser> userList = this.genUserByMobileList(mobileList);
                cusUserBiz.batchCreateUser(userList);
                return ResultUtil.SUCCESS();
            }else {
                return ResultUtil.ERROR();
            }

        }catch (Exception e){
            return ResultUtil.ERROR();
        }
    }

    //=========================================================
    /**
     * 替换不支持的字符
     *
     * @param input 输入
     * @return 替换后的字符串
     */
    private String replaceUnsupportedCharSequence(String input) {
        return input == null ? "" : input.replaceAll("([^\u0020-\u007E\u00A1-\uFFFF])", "?");
    }

    /**
     * 处理用户选择ID串中已被删除的专业id
     * @param cusUser
     */
    private void dealWithDeleteUserNatyralSubjectIds(CusUser cusUser){
        Set<String> old = getParentSet(cusUser.getNaturalSubjectIds());
        if(ObjectUtils.isNotEmpty(old)){
            StringBuffer stringBuffer = new StringBuffer();
            old.stream().forEach(v -> stringBuffer.append(v).append(","));
            String subjectIds = StringUtils.subHeadTailString(stringBuffer.toString(),",");
            SysSubject sysSubject =new SysSubject();
            sysSubject.setQueryIds(subjectIds);
            List<SysSubject> subjectList = sysSubjectBiz.findSubjectList(sysSubject);
            if(subjectList.size() < old.size()){//查询专业id数小于用户原有专业id数，则存在已删除专业id，将其剔除，否则不做任何处理
                if(ObjectUtils.isNotEmpty(subjectList)){
                    subjectList.forEach(v -> {
                        String id = v.getId().toString();
                        if(old.contains(id)){
                            old.remove(id);
                        }
                    });
                }
                String[] array = cusUser.getNaturalSubjectIds().split("#");
                StringBuffer stringBuffer1 = new StringBuffer();
                Arrays.stream(array).forEach(v -> {
                    old.stream().forEach(e -> {
                        int index = v.indexOf(","+e+",");
                        if(index == -1){
                            stringBuffer1.append(v).append("#");
                        }
                    });
                });
                cusUser.setNaturalSubjectIds(StringUtils.subHeadTailString(stringBuffer1.toString(),"#"));
            }
        }
    }

    /**
     * 验证用户自然添加的专业/科目数据
     * @param old 原有的专业数据
     * @param now 新添加的专业数据
     * @return 返回null验证通过，非null验证不通过
     */
    private Map<String,Object> vUserNaturalSubjectIds(String old,String now){
        if(StringUtils.isNotEmpty(now)){
            if(StringUtils.isEmpty(old)){//如果没有设置专业
                Set<String> set = getParentSet(now);
                if(set.size()>3){
                    return ResultUtil.ERROR("最多可设置3个专业");
                }
            }else{//如果有设置专业
                Set<String> oldSet = getParentSet(old);
                Set<String> nowSet = getParentSet(now);
                Set<String> newSet = new HashSet<>();
                oldSet.forEach(s ->{
                    newSet.add(s);
                });
                nowSet.forEach(s ->{
                    newSet.add(s);
                });
                if(newSet.size()>3){
                    return ResultUtil.ERROR("最多可设置3个专业");
                }
            }
        }
        return null;
    }

    /**
     * 获取父级专业ID的Set集合
     * @param subjectIds
     * @return Set<String>
     */
    private Set<String> getParentSet(String subjectIds){
        Set<String> set = new HashSet<>();
        if(StringUtils.isNotEmpty(subjectIds)){
            subjectIds = subjectIds.replaceAll("＃","#");
            String[] arr = subjectIds.split("#");
            Arrays.stream(arr).forEach(str->{
                if(StringUtils.isNotEmpty(str)){
                    str = StringUtils.subHeadTailString(str,",");
                    set.add(str.split(",")[0]);
                }
            });
        }
        return set;
    }


    /**
     * 用于分销用户导入
     *
     * @param mobileList 手机号集合
     * @return List<User>
     */
    private List<CusUser> genUserByMobileList(List<String> mobileList) {
        List<CusUser> userList = new ArrayList<>();
        for (String mobile : mobileList) {
            CusUser user = new CusUser();
            user.setEmailIsavalible(0);
            user.setMobile(mobile);
            user.setMobileIsavalible(1);
            user.setPassword("111111");
            user.setRegisterType(2);
            user.setRegisterFrom(UserExpandFrom.adminFrom.getKey());
            user.setIsavalible(1);
            user.setGender(0);
            user.setUserType(3);
            user.setBuyCourse(1);
            user.setStudyTotalTime(0);
            user.setStudyNum(0);
            user.setLoginNum(0);
            user.setSignNum(0);
            user.setStudyNum(0);
            user.setJoinLiveCount(0);
            user.setAssessNum(0);
            user.setExamNum(0);
            user.setQaNum(0);
            user.setNoteNum(0);
            user.setIsWifi(1);
            userList.add(user);
        }
        return userList;
    }

    /**
     *  更改用戶购买状态
     * @param userId 用户Id
     */
    @RequestMapping("/updateUserBuyCourse")
    public void updateUserBuyCourse(@RequestParam("userId") BigDecimal userId) {
        cusUserBiz.updateUserBuyCourse(userId);
    }

    /**
     * 查询用户考试可以选择的专业
     * @param userId 用户ID
     * @return 专业列表
     */
    @RequestMapping("/findUserExamSelectSubjectList")
    public List<SysSubject> findUserExamSelectSubjectList(@RequestParam("userId") BigDecimal userId){
        List<SysSubject> subjectList = cusUserBiz.findAllUserSubjectList(userId);
        if(ObjectUtils.isEmpty(subjectList)){//如果用户没有配置专业，则获取系统的所有专业
            SysSubject sysSubject = new SysSubject();
            sysSubject.setStatus(1);
            subjectList = sysSubjectBiz.findLayeredSubjectList(sysSubject);
        }
        return subjectList;
    }

    /**
     * 获取用户的所有的专业（基础专业和附加专业）
     * @param userId 用户ID
     * @return List<SysSubject>
     */
    @RequestMapping("/findAllUserSubjectList")
    public List<SysSubject> findAllUserSubjectList(@RequestParam("userId") BigDecimal userId){
        List<SysSubject> subjectList = cusUserBiz.findAllUserSubjectList(userId);
        return subjectList;
    }
    /**
     * 验证账号是否存在
     * @param account 用户ID
     * @return
     */
    @RequestMapping("/verifyAccount")
    public Map<String,Object> verifyAccount(@RequestParam("account") String account){
        CusUser longUser = cusUserBiz.getLongUser(account);
        boolean flag =false;
        if(ObjectUtils.isEmpty(longUser)){
            flag =true;
        }
        return ResultUtil.SUCCESS("验证成功",flag);
    }

    /**
     * 获取用户的所有专业ID串
     * @param userId 用户ID
     * @return  String
     */
    @RequestMapping("/findUserAllSubjectIds")
    public String findUserAllSubjectIds(@RequestParam("userId") BigDecimal userId){
        CusUser user = cusUserBiz.findById(userId);
        String _ids = "";
        String subjectIds = user.getSubjectIds();
        if(StringUtils.isNotEmpty(subjectIds)){
            _ids += subjectIds;
        }
        String naturalSubjectIds = user.getNaturalSubjectIds();
        if(StringUtils.isNotEmpty(naturalSubjectIds)){
            _ids +="#" +naturalSubjectIds;
        }
        if(StringUtils.isNotEmpty(_ids)){
            String[] arr = _ids.split("#");
            Set<String> idSet = new LinkedHashSet<>();
            Arrays.stream(arr).forEach(str ->{
                String _str = StringUtils.subHeadTailString(str,",");
                if(StringUtils.isNotEmpty(_str)){
                    String[] _arr = _str.split(",");
                    Arrays.stream(_arr).forEach(s->{
                        if(StringUtils.isNotEmpty(s)){
                            idSet.add(s);
                        }
                    });
                }
            });
            if(ObjectUtils.isNotEmpty(idSet)){
                return idSet.stream().collect(Collectors.joining(","));
            }
        }
        return null;
    }

    /**
     * 执行导入试题文件
     * @param multipartFile 试题文件
     * @param sysUserId 创建的系统用户ID
     * @return Map<String, Object>
     */
    @RequestMapping(value = "/importUser", method = {RequestMethod.POST}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Map<String,Object> importUser(@RequestPart(value = "file") MultipartFile multipartFile,
                                                 @RequestParam("sysUserId") BigDecimal sysUserId) {
        HSSFWorkbook workBook;
        try {
            workBook = new HSSFWorkbook(multipartFile.getInputStream());
        } catch (Exception e) {
            return ResultUtil.ERROR("读取Excel表格数据错误");
        }
        //只读取sheet1
        HSSFSheet sheet = workBook.getSheetAt(0);
        int rows = sheet.getPhysicalNumberOfRows(); //excel中实际行数
        if (rows == 1) {
            return ResultUtil.ERROR("xls表格中没有填写数据");
        }
        if (rows-1 > 2000) {
            return ResultUtil.ERROR("xls表中的数据不能多于2000行");
        }
        HSSFRow row;
        HSSFCell cell;
        LinkedHashSet<CusUser> cusUserLinkedHashSet= new LinkedHashSet<>();
        for (int i = 1; i <= rows; i++) {
            CusUser  user = new CusUser();
            // 读取行为第2行开始
            row = sheet.getRow(i);
            if (row != null) {
                row.getPhysicalNumberOfCells();
                // **读取行中的列**
                cell = row.getCell((short) 0);//手机号
                if (cell != null) {
                    cell.setCellType(CellType.STRING);
                    String mobile = cell.getStringCellValue().trim();
                    user.setMobile(mobile);
                }
                cell = row.getCell((short) 1);//账号
                if (cell != null) {
                    cell.setCellType(CellType.STRING);
                    String loginAccount = cell.getStringCellValue();
                    user.setLoginAccount(loginAccount);
                }
                cell = row.getCell((short) 2);//邮箱
                if (cell != null) {
                    String email = cell.getStringCellValue().trim();
                    user.setEmail(email);
                }
                cell = row.getCell((short) 3);//获取密码
                String password=null;
                if (cell != null) {
                    cell.setCellType(CellType.STRING);
                    password = cell.getStringCellValue().trim();
                }
                cell = row.getCell((short) 4);//课程ID串
                if (cell != null) {
                    cell.setCellType(CellType.STRING);
                    String courseIds = cell.getStringCellValue().trim();
                    user.setCourseIds(courseIds);
                }
                user.setRegisterFrom(UserExpandFrom.adminFrom.getKey());
                user.setPassword(password);
                user.setIsavalible(1);
                user.setStatus(1);
                cusUserLinkedHashSet.add(user);
            }
        }
        if(ObjectUtils.isEmpty(cusUserLinkedHashSet)){
            return ResultUtil.ERROR("Excel表中没有用户数据");
        }
        List<CusUser> cusUserList = new ArrayList<>();
        //验证用户数据
        Map<String,Object> resultMap = this.vUserListData(cusUserLinkedHashSet,cusUserList);
        if(resultMap != null){
            return resultMap;
        }
        if(ObjectUtils.isEmpty(cusUserList)){
            return ResultUtil.ERROR("Excel中没有正确的用户数据");
        }
        //保存用户数据
        cusUserBiz.batchCreateUser(cusUserList);
        return ResultUtil.SUCCESS("用户数据导入成功");
    }

    /**
     * 获取用户的所有专业ID串
     * @param users 用户ID
     * @return  String
     */
    @RequestMapping("/createBatchUser")
    public Map<String,Object> createBatchUser(@RequestBody  List<CusUser> users){
        //保存用户数据
        cusUserBiz.batchCreateUser(users);
        return ResultUtil.SUCCESS("用户数据导入成功");
    }




    /**
     * 验证导入的用户数据
     * @param cusUserLinkedHashSet 用户数据列表
     * @param cusUserList 正确的用户数据
     * @return Map<String,Object>
     */
    private Map<String,Object> vUserListData(LinkedHashSet<CusUser> cusUserLinkedHashSet,List<CusUser> cusUserList){
        Iterator<CusUser> cusUserIterator = cusUserLinkedHashSet.iterator();
        int rowNum = 1;
        while (cusUserIterator.hasNext()){
            rowNum ++;
            CusUser cusUser = cusUserIterator.next();
            String mobile = cusUser.getMobile();
            String loginAccount = cusUser.getLoginAccount();
            String email = cusUser.getEmail();
            String password = cusUser.getPassword();

            String rowStr = "第"+rowNum+"行的";
            if(StringUtils.isEmpty(mobile) && StringUtils.isEmpty(loginAccount) && StringUtils.isEmpty(email)){
                return ResultUtil.ERROR(rowStr+"手机号、账号、邮箱号必填其中一列");
            }
            if(StringUtils.isNotEmpty(mobile)){
                if(!StringUtils.isMobile(mobile)){
                    return ResultUtil.ERROR(rowStr+"请填写正确的手机号");
                }else{
                    CusUser mobileUser = cusUserBiz.queryUserByMobile(mobile.trim());
                    if(ObjectUtils.isNotEmpty(mobileUser)){
                        return ResultUtil.ERROR(rowStr + "手机号已被使用");
                    }
                }
                cusUser.setMobileIsavalible(1);
            }
            if(StringUtils.isNotEmpty(loginAccount)){
                Pattern pat = Pattern.compile("^[A-Za-z0-9]{6,20}$");
                Matcher matcher = pat.matcher(loginAccount.trim());
                if (!matcher.matches()) {
                    return ResultUtil.ERROR(rowStr + "账号错误，账号只是英文与数字组合，且长度6-20位！");
                }else{
                    if (ObjectUtils.isNotEmpty(cusUserBiz.queryUserByLoginAccount(loginAccount))) {
                        return ResultUtil.ERROR(rowStr + "账号已被使用");
                    }
                }
                cusUser.setLoginAccount(loginAccount.trim());
            }
            if(StringUtils.isNotEmpty(email)){
                if(!StringUtils.isEmail(email)){
                    return ResultUtil.ERROR(rowStr+"请填写正确的邮箱号");
                }else{
                    CusUser emailUser = cusUserBiz.queryUserByEmail(email.trim());
                    if(ObjectUtils.isNotEmpty(emailUser)){
                        return ResultUtil.ERROR(rowStr+"邮箱号已被使用");
                    }
                }
                cusUser.setEmailIsavalible(1);
            }

            if(StringUtils.isNotEmpty(password)){
                if(!StringUtils.isLetterOrNum(password)){
                    return ResultUtil.ERROR(rowStr + "登录密码只能是大小字英文和数据结合");
                }
                if(password.trim().length()< 6 || password.trim().length() > 20){
                    return ResultUtil.ERROR(rowStr + "登录密码长度必须在6-20位之间");
                }
                cusUser.setPassword(password.trim());
            }else{
                cusUser.setPassword("111111");
            }
            cusUserList.add(cusUser);
        }
        if(ObjectUtils.isNotEmpty(cusUserList)){
            Map<String,List<CusUser>> mobileUserListMap = cusUserList.stream().filter(e->StringUtils.isNotEmpty(e.getMobile())).collect(Collectors.groupingBy(e->e.getMobile()));
            Map<String,List<CusUser>> loginAccountUserListMap = cusUserList.stream().filter(e->StringUtils.isNotEmpty(e.getLoginAccount())).collect(Collectors.groupingBy(e->e.getLoginAccount()));
            Map<String,List<CusUser>> emailUserListMap = cusUserList.stream().filter(e->StringUtils.isNotEmpty(e.getEmail())).collect(Collectors.groupingBy(e->e.getEmail()));
            for (int i = 0; i < cusUserList.size(); i++) {
                String rowStr = "第"+(i+2)+"行的";
                CusUser cusUser = cusUserList.get(i);
                String mobile = cusUser.getMobile();
                String loginAccount = cusUser.getLoginAccount();
                String email = cusUser.getEmail();
                if(StringUtils.isNotEmpty(mobile)){
                    List<CusUser> mobileUserList = mobileUserListMap.get(mobile);
                    if(ObjectUtils.isNotEmpty(mobileUserList)){
                        if(mobileUserList.size() >1){
                            return ResultUtil.ERROR(rowStr + "手机号有重复的");
                        }
                    }
                }
                if(StringUtils.isNotEmpty(loginAccount)){
                    List<CusUser> loginAccountUserList = loginAccountUserListMap.get(loginAccount);
                    if(ObjectUtils.isNotEmpty(loginAccountUserList)){
                        if(loginAccountUserList.size()>1){
                            return ResultUtil.ERROR(rowStr + "账号有重复的");
                        }
                    }
                }
                if(StringUtils.isNotEmpty(email)){
                    List<CusUser> emailUserList = emailUserListMap.get(email);
                    if(ObjectUtils.isNotEmpty(emailUserList)){
                        if(emailUserList.size()>1){
                            return ResultUtil.ERROR(rowStr + "邮箱号有重复的");
                        }
                    }
                }
            }
        }
        return null;
    }


    /**
     * 根据某一字段拼接的字符串查询
     * @param field
     * @param valueStr
     * @return
     */
    @RequestMapping("/queryUserByFieldValueStr")
    public List<CusUser> queryUserByFieldValueStr(@RequestParam("field")String field, @RequestParam("valueStr")String valueStr){
        return cusUserBiz.queryUserByFieldValueStr(field, valueStr);
    }

    /**
     * 赠送课程
     * @param map
     * @return
     */
    @RequestMapping("/creatGifts")
    public String creatGifts(@RequestBody Map map) {
        return  cusUserBiz.creatGifts(map);
    }


    /**
     * 上传学员
     * @param
     * @return
     */
    @RequestMapping("/createExcelUser")
    public Map<String,Object>  createExcelUser(@RequestBody CusUser cusUser) {
        try {
            cusUserBiz.createExcelUser(cusUser);

        }catch (IllegalArgumentException e){
            e.printStackTrace();
            return ResultUtil.ERROR("用户创建失败! </br>");
        }catch (RuntimeException e){
            return ResultUtil.ERROR(new  StringBuffer("赠送的商品出现问题,用户创建失败!").append(e.getMessage()).append("</br>").toString());
        }
        return ResultUtil.SUCCESS("创建成功");
    }

    /**
     * 学员学习中心历史数据统计
     */
    @RequestMapping("/learningNumerical")
    @ResponseBody
    public Map<String, Object> learningNumerical(@RequestBody Map params ) {

        return  cusUserBiz.learningNumerical(params);
    }
}
